package com.ak.jddemo.test;

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author: lianghuan
 * @date: 2021/1/5 22:26
 */
@Service
@Slf4j
public class HttpUrlConnectionUtil {
    static ArrayList<String> ipList = new ArrayList<>();
    static AtomicInteger id = new AtomicInteger();
    static AtomicInteger times = new AtomicInteger();

    /**
     * get请求
     *
     * @param headers 请求头，可为空
     * @param url
     * @return
     * @throws IOException
     */
    public static String get(JSONObject headers, String url) throws IOException {
        URLConnection urlConnection;
        urlConnection = new URL(url).openConnection();
        String response = "";
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
        httpURLConnection.setRequestMethod("GET");
        if (headers != null) {
            for (String headerName : headers.keySet()) {
                httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
            }
        }
        httpURLConnection.connect();
        if (httpURLConnection.getResponseCode() == 200) {
            InputStream inputStream = httpURLConnection.getInputStream();
            byte[] buffer;
            buffer = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(buffer)) != -1) {
                response = response + new String(buffer, 0, length, "UTF-8");
            }
            httpURLConnection.disconnect();
        }
        return response;
    }




    /**
     * 获取并保存二维码
     *
     * @param headers
     * @param url
     * @return
     * @throws IOException
     */
    public static String getQCode(JSONObject headers, String url) throws IOException {
        URLConnection urlConnection;
        urlConnection = new URL(url).openConnection();
        String response = "";
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
        httpURLConnection.setRequestMethod("GET");
        if (headers != null) {
            Iterator<String> iterator = headers.keySet().iterator();
            while (iterator.hasNext()) {
                String headerName = iterator.next();
                httpURLConnection.setRequestProperty(headerName, headers.get(headerName).toString());
            }
        }
        httpURLConnection.connect();
        if (httpURLConnection.getResponseCode() == 200) {
            InputStream inputStream = httpURLConnection.getInputStream();
            OutputStream outputStream = new FileOutputStream("QCode.png");
            byte[] buffer;
            int length;
            buffer = new byte[1024];
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
                response = response + new String(buffer, 0, length, "GBK");
            }
            outputStream.close();
            httpURLConnection.disconnect();
        }
        return response;
    }

    /**
     * date字符串转时间戳
     *
     * @param date
     * @return
     */
    public static Long dateToTime(String date) throws ParseException {
        SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date data = sdfTime.parse(date);
        Long time = data.getTime();
        return time;
    }

    /**
     * time时间戳转Date
     *
     * @param time
     * @return
     */
    public static Date timeToDate(long time) {
        SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = sdfTime.format(time);
        try {
            Date date = sdfTime.parse(str);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getGapTime(long ms) {
        Integer ss = 1000;
        Integer mi = ss * 60;
        Integer hh = mi * 60;
        Integer dd = hh * 24;

        Long day = ms / dd;
        Long hour = (ms - day * dd) / hh;
        Long minute = (ms - day * dd - hour * hh) / mi;
        Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

        StringBuffer sb = new StringBuffer();
        if (day > 0) {
            sb.append(day + "天");
        }
        if (hour > 0) {
            sb.append(hour + "小时");
        }
        if (minute > 0) {
            sb.append(minute + "分");
        }
        if (second > 0) {
            sb.append(second + "秒");
        }
        if (milliSecond > 0) {
            sb.append(milliSecond + "毫秒");
        }
        return sb.toString();
    }

    public static ArrayList<String> ips() throws IOException {
        String path = "http://api.xiequ.cn/VAD/GetIp.aspx?act=get&uid=63079&vkey=779D829F233916DA52B6BE16C15F256B&num=200&time=30&plat=1&re=0&type=2&so=1&ow=1&spl=1&addr=&db=1";
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        conn.setRequestProperty("contentType", "GBK");
        conn.setConnectTimeout(5 * 1000);
        conn.setRequestMethod("GET");
        InputStream inStream = conn.getInputStream();
        // readLesoSysXML(inStream);
        BufferedReader in = new BufferedReader(new InputStreamReader(inStream, StandardCharsets.UTF_8));
        StringBuffer buffer = new StringBuffer();
        ArrayList<String> ipp = new ArrayList<String>();
        String line = "";
        // 读取获取到内容的最后一行,写入
        while ((line = in.readLine()) != null) {
            buffer.append(line);
            ipp.add(line);
        }

        return ipp;

    }

    /**
     * 获取抢购连接
     */
    public static String getTargetUrl(JSONObject headers) throws IOException, ParseException, InterruptedException {
        long time = System.currentTimeMillis();
        int randomInt = (int) (1000000 + Math.random() * (9999999 - 1000000 + 1));
        String pid = Config.pid;
        String url = "https://itemko.jd.com/itemShowBtn?callback=jQuery" + randomInt + "&skuId=" + pid + "&from=pc&_=" + time;
        log.info("获取抢购连接");
        String response = HttpUrlConnectionUtil.doGet(url, headers);
        response = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
        String targetUri = JSONObject.parseObject(response).get("url").toString();
        if (targetUri == null || targetUri.equals("")) {
            log.info("获取抢购连接失败,进入普通抢购模式");
            Config.seckillMode = false;
            SeckillUtils.checkTime();
            SeckillService.begin();
            System.exit(0);
//            if (times.incrementAndGet()> SeckillService2.ERROR_TIMES) {
//                log.info("已到最大尝试次数，结束程序");
//                System.exit(0);
//            }else {
//                log.info("尝试重新获取抢购连接");
//                return getTargetUrl(headers);
//            }
        }
        return "https:" + JSONObject.parseObject(response).get("url").toString();
    }

    /**
     * 发送结算请求
     */
    public static void sendClearingUrl(JSONObject headers, String targetUrl) throws IOException {
        log.info("发送结算请求");
        String s = HttpUrlConnectionUtil.doGet(targetUrl, headers);
    }

    public static JSONObject getInitMsg(JSONObject headers) throws IOException {
        String url = "https://marathon.jd.com/seckillnew/orderService/pc/init.action";
        JSONObject param = new JSONObject();
        param.put("sku", Config.pid);
        param.put("num", 1);
        param.put("isModifyAddress", "false");
        String response = HttpUrlConnectionUtil.doPost(url, param, headers,false);
        return JSONObject.parseObject(response);
    }

    public static String doPost(String url, JSONObject param, JSONObject headers,boolean enabledProxy) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            if (enabledProxy) {
                httpClient = setProxy(httpPost);
            }
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key).toString()));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "utf-8");
                httpPost.setEntity(entity);
            }
            for (Map.Entry<String, Object> entry : headers.entrySet()) {
                httpPost.setHeader(entry.getKey(), entry.getValue().toString());
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }

    public static String doGet(String url, JSONObject headers) throws IOException {
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建http GET请求
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            for (Map.Entry<String, Object> entry : headers.entrySet()) {
                httpGet.setHeader(entry.getKey(), entry.getValue().toString());
            }
            // 执行请求
            response = httpclient.execute(httpGet);
            return EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
            //相当于关闭浏览器
            httpclient.close();
        }
        // 判断返回状态是否为200
        return "";
    }

    public static CloseableHttpClient setProxy(HttpPost httpPost) {
        int proxyId = id.incrementAndGet() % Config.ipPool.size();
        String[] ipInfo = Config.ipPool.get(proxyId).split(":");
        String host = ipInfo[0];
        int port = Integer.parseInt(ipInfo[1]);
        log.info("代理ip{},端口{}", host, port);
        // 创建httpClient实例
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //设置代理IP、端口
        HttpHost proxy = new HttpHost(host, port, "http");
        RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).build();
        httpPost.setConfig(requestConfig);
        return httpClient;
    }

}
